package com.dankegongyu.lib.common.util;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

/**
 * 用于解决因为沉浸式状态栏，但不想采用fitSystemWidnow属性
 * 或不想设置键盘属adjustResize/adjustPan属性，想实现键盘不遮挡输入框
 * Created by SmileXie on 2017/3/27.
 */
public class KeyboardCompat {

    private View rootView;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams rootViewParams;
    private int contentHeight;
    private boolean isFirst = true;
    private int statusBarHeight;

    /**
     * 设置沉浸式状态栏时，adjustResize可能失效，界面无法滚动，调用该方法即可
     *
     * @param activity target Activity
     */
    public static void assist(Activity activity) {
        new KeyboardCompat(activity);
    }

    private KeyboardCompat(Activity activity) {
        statusBarHeight = getStatusBarHeight();
        // DecorView
        FrameLayout content = activity.findViewById(android.R.id.content);
        // setContentView放进去的View
        rootView = content.getChildAt(0);

        // 给Activity的xml布局设置View树监听，当布局有变化，如键盘弹出或收起时，都会回调此监听
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                if (isFirst) {
                    contentHeight = rootView.getHeight();//兼容华为等机型
                    isFirst = false;
                }
                // 当前布局发生变化时，对Activity的xml布局进行重绘
                possiblyResizeRootView();
            }
        });

        rootViewParams = (FrameLayout.LayoutParams) rootView.getLayoutParams();
    }

    /**
     * 获取界面可用高度，如果软键盘弹起后，Activity的xml布局可用高度需要减去键盘高度
     */
    private void possiblyResizeRootView() {
        // 获取当前界面可用高度，键盘弹起后，当前界面可用布局会减少键盘的高度
        int usableHeightNow = computeUsableHeight();
        //当前可见高度和上一次可见高度不一致 布局变动
        if (usableHeightNow != usableHeightPrevious) {
            // 获取Activity中xml中布局在当前界面显示的高度
            int usableHeightSansKeyboard = rootView.getRootView().getHeight();
            // Activity中xml布局的高度-当前可用高度
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            // 高度差大于屏幕1/4时，说明键盘弹出
            int heightLimit = usableHeightSansKeyboard / 4;
            if (heightDifference > heightLimit) {
                // 键盘弹出了，Activity的xml布局高度应当减去键盘高度
//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//                    rootViewParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
//                } else {
                rootViewParams.height = usableHeightSansKeyboard - heightDifference;
//                }
            } else {
                rootViewParams.height = contentHeight;
            }
            rootView.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    /**
     * 获取改变之后界面的可用高度（可以为开发者显示内容的高度）
     *
     * @return
     */
    private int computeUsableHeight() {
        Rect r = new Rect();
        rootView.getWindowVisibleDisplayFrame(r); // 获取到的rect就是界面除去标题栏、除去软键盘挡住部分，所剩下的域
        return (r.bottom - r.top);
    }

    /**
     * 获取状态栏高度(px)
     *
     * @return 状态栏高度px
     */
    public static int getStatusBarHeight() {
        Resources resources = Resources.getSystem();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        return resources.getDimensionPixelSize(resourceId);
    }

}